﻿namespace Tszy.Unlimited.Base.Collections;

/// <summary>
/// 字节队列。
/// </summary>
public class ByteQueue
{
    /// <summary>
    /// 位置。
    /// </summary>
    private int _index = 0;

    /// <summary>
    /// 每项的位置集合。
    /// </summary>
    private readonly int[] _itemIndexList;

    /// <summary>
    /// 集合序号。
    /// </summary>
    private int _itemIndex = 0;

    /// <summary>
    /// 初始化。
    /// </summary>
    /// <param name="maxSize">最大字节数。</param>
    /// <param name="itemCount">数据块的总数。</param>
    public ByteQueue(int maxSize, int itemCount)
    {
        data = (new byte[maxSize]);
        _itemIndexList = new int[itemCount];
    }

    private readonly byte[] data;

    /// <summary>
    ///
    /// </summary>
    public byte[] GetData()
    {
        return data;
    }

    /// <summary>
    ///
    /// </summary>
    /// <param name="data"></param>
    public void Add(byte[] data)
    {
        if (data == null)
            return;

        // 将 data 填充到 _bytes 里，索引是 _index 开始。
        data.CopyTo(GetData(), _index);

        _itemIndexList[_itemIndex] = _index;

        _index += data.Length;
        _itemIndex++;
    }

    /// <summary>
    /// 获得指定序号的块数据。
    /// </summary>
    /// <remarks>
    /// --------------------------------------------------------------------
    /// [ 数据块 4 byte 序号 1 | 数据块 4 byte 序号 2 | 数据块 4 byte 序号 3
    /// --------------------------------------------------------------------
    /// </remarks>
    /// <param name="index">序号。</param>
    /// <returns>块数据。</returns>
    public byte[] Get(int index)
    {
        if (index > _itemIndex)
            throw new ArgumentOutOfRangeException(nameof(index));

        var startIndex = _itemIndexList[index];
        var length = _index;

        if (index < _itemIndex - 1)
        {
            length = _itemIndexList[index + 1] - startIndex;
        }
        else
        {
            length -= startIndex;
        }

        var data = new byte[length];

        Array.Copy(GetData(), startIndex, data, 0, length);

        return data;
    }
}
